#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include "fr30xx.h"
#include "user_bt.h"
#include "assert.h"
#include "app_task.h"
#include "FreeRTOS.h"
#include "timers.h"
#include "btdm_mem.h"
#include "app_audio.h"
#include "fr_device_pa.h"
#include "driver_i2s.h"
#include "app_dac.h"
#include "driver_psd_dac.h"
#include "sbc.h"
#include "y_ringbuf.h"
#include "queue.h"
//#include "codec.h"
//#include "audio_decoder.h"
//#include "audio_common.h"

// SBC解码相关函数声明 - 移到文件开头
static void play_audio_via_sbc_decode(uint8_t *sbc_data, uint32_t length);
static bool send_sbc_data_to_decode_task(uint8_t *sbc_data, uint32_t length);
static bool start_sbc_decode_task(void);
static void stop_sbc_decode_task(void);
static void sbc_decode_task(void *pvParameters);
static void audio_set_playing_state(bool playing);

#define MAX_RECONNECT_TIMES 3   //reconnect times if page timeout or linkloss
#define PAGE_TIMEOUT    0x1000   //connect timeout value, uint:625us
#define MAX_NAME_SIZE   24
#define SCO_DATA_BUFFER_COUNT       3

///enable audio transfer, audio is transfered from phone to earphone
#define ENABLE_AUDIO_TRANSFER

#ifdef ENABLE_AUDIO_TRANSFER
uint8_t voice_phone_data[120];
uint8_t voice_headset_data[120];
#endif

struct sco_data_t {
    struct co_list_hdr hdr;
    void *arg;
    uint16_t length;
    uint8_t data[];
};

struct sbc_info_t{
    uint8_t elem[4];
    SbcStreamInfo info;
};

const uint8_t hf_enable_voltage_notify[] = "AT+XAPL=AAAA-1111-01,10";
const uint8_t hf_search_remote_dev_type[] = "AT+CGMI";

struct user_bt_env_t user_bt_env;
static TimerHandle_t bt_connect_timer = NULL;
static TimerHandle_t bt_avrcp_connect_timer = NULL;
static TimerHandle_t bt_a2dp_connect_timer = NULL;
static TimerHandle_t bt_linkloss_connect_timer = NULL;

struct sbc_info_t sbcinfo[NUM_BT_DEVICES];
static void bt_save_codec_info(uint8_t dev_index, uint8_t *elements)
{
    memcpy(&sbcinfo[dev_index].elem[0], elements, 4);
    /* copy codec info to local*/
    sbcinfo[dev_index].info.bitPool = elements[3];
    if(elements[0]&0x20){
        sbcinfo[dev_index].info.sampleFreq = 2;//44100
    }
    else{
        sbcinfo[dev_index].info.sampleFreq = 3;//48000
    }
    sbcinfo[dev_index].info.allocMethod = elements[1]&0x03; //1-->loudness, 2--->snr
    
    if(elements[1]&0x10){
        sbcinfo[dev_index].info.numBlocks = 16;
    }
    else if(elements[1]&0x20){
        sbcinfo[dev_index].info.numBlocks = 12;
    }
    else if(elements[1]&0x40){
        sbcinfo[dev_index].info.numBlocks = 8;
    }
    else{
        sbcinfo[dev_index].info.numBlocks = 4;
    }
    
    if(elements[1]&0x04){
        sbcinfo[dev_index].info.numSubBands = 8;
    }
    else{
        sbcinfo[dev_index].info.numSubBands = 4;
    }
}

static uint16_t sbc_calc_frame_len(struct sbc_info_t *info)
{
    uint16_t temp = (1*info->info.numSubBands) + (info->info.numBlocks*info->info.bitPool);
    uint16_t frame_len = 4 + ((4*info->info.numSubBands*info->info.numChannels)>>3) + (temp>>3);
    if(temp%8){
        frame_len++;
    }   
    return frame_len;
}

uint8_t bt_get_free_dev(void)
{
    uint8_t index;
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(user_bt_env.dev[index].state == BT_LINK_STATE_IDLE){
            break;
        }
    }
    return index;
}

uint8_t bt_find_dev_index(BD_ADDR *addr)
{
    uint8_t index;
    printf("find dev :%x,%x,,%x\r\n",addr->A[0],addr->A[1],user_bt_env.dev[0].remote_bd.A[0]);
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(memcmp(&user_bt_env.dev[index].remote_bd, addr, sizeof(BD_ADDR)) == 0){
            break;
        }
    }
    return index;
}
uint8_t bt_find_dev_index_by_dev(void *dev)
{
    uint8_t index;
    if(dev == NULL){
     return NUM_BT_DEVICES;
    }
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(user_bt_env.dev[index].remDev == dev){
            break;
        }
    }
    return index;
}

uint8_t bt_find_dev_index_by_hfchan(HfChannel *chan)
{
    uint8_t index;
    if(chan == NULL){
     return NUM_BT_DEVICES;
    }
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(user_bt_env.dev[index].hf_chan == chan){
            break;
        }
    }
    return index;
}

uint8_t bt_find_dev_index_by_hfgchan(HfgChannel *chan)
{
    uint8_t index;
    if(chan == NULL){
     return NUM_BT_DEVICES;
    }
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(user_bt_env.dev[index].hfg_chan == chan){
            break;
        }
    }
    return index;
}

uint8_t bt_find_dev_index_by_rcpchan(AvrcpChannel *chan)
{
    uint8_t index;
    if(chan == NULL){
     return NUM_BT_DEVICES;
    }
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(user_bt_env.dev[index].rcp_chan == chan){
            break;
        }
    }
    return index;
}

uint8_t bt_find_dev_index_by_pbapclient(PbapClientSession *client)
{
    uint8_t index;
    if(client == NULL){
     return NUM_BT_DEVICES;
    }
    for(index = 0; index < NUM_BT_DEVICES; index++){
        if(user_bt_env.dev[index].pbap_client == client){
            break;
        }
    }
    return index;
}

static void bt_parse_inq_result(uint8_t *input, uint8_t *name, uint8_t *len)
{
    uint8_t i = 0,k = 0;
    uint8_t *ptr = input;
    
    *len = 0;
    while(i<240){
        if(*(ptr + i) == 0){
            break;//i = 240;
        }else{
            if(*(ptr+1+i) == 0x09){
                *len = *(ptr+i);
                k = i;
                break;//i = 240;
            }else{
                i += *ptr + 1;
            }
        }
    }
    if(*len > MAX_NAME_SIZE){
        memcpy(name,input+k+2,MAX_NAME_SIZE);
    }   
    else if(*len > 0){
        memcpy(name,input+k+2,*len);
    }
}


BtStatus bt_do_connect(BD_ADDR *addr, uint8_t profiles, void **chan)
{
    BtStatus ret = BT_STATUS_FAILED;
    uint8_t index = 0;
    printf("bt do connect\r\n");
    if((profiles & user_bt_env.enable_profiles) == profiles){
        //connect to remote device depending on the profile
        if(profiles & ENABLE_PROFILE_HF){
            index = bt_get_free_hf_channel();
            if(index < NUM_BT_DEVICES){
            ret = HF_CreateServiceLink(&hf_channel[index], addr);
                *chan = (void *)&hf_channel[index];            
            }
        }
        else if(profiles & ENABLE_PROFILE_HFG){
            index = bt_get_free_hfg_channel();
            if(index < NUM_BT_DEVICES){
            ret = HFG_CreateServiceLink(&hfg_channel[index], addr);
                *chan = (void *)&hfg_channel[index]; 
            }
        }
        else if(profiles & ENABLE_PROFILE_A2DP_SINK){
            index = bt_get_free_a2dp_sink_stream();
            if(index < NUM_BT_DEVICES){
            ret = A2DP_OpenStream(&Stream[index],addr);
                *chan = (void *)&Stream[index];
            }
        }
        else if(profiles & ENABLE_PROFILE_A2DP_SOURCE){
            index = bt_get_free_a2dp_source_stream();
            if(index < NUM_STREAMS){
            ret = A2DP_OpenStream(&Stream[index],addr);
                *chan = (void *)&Stream[index];
            }
        }
        else if(profiles & ENABLE_PROFILE_HID){
        
        }
        else if(profiles & ENABLE_PROFILE_SPP){
        
        }    
    }

    return ret;
}

BtStatus bt_do_disconnect(BD_ADDR *addr, CmgrHandler *handler,uint8_t force)
{
    uint8_t dev_index;
    BtStatus status = BT_STATUS_PENDING;
    
    dev_index = bt_find_dev_index(addr);
    xTimerStop(bt_connect_timer,portMAX_DELAY);
    xTimerStop(bt_avrcp_connect_timer,portMAX_DELAY);
    xTimerStop(bt_a2dp_connect_timer,portMAX_DELAY);
    xTimerStop(bt_linkloss_connect_timer,portMAX_DELAY);
    user_bt_env.connect_times = 0;

    printf("bt do disconnect\r\n");
    if(force == true){
        if(user_bt_env.dev[dev_index].remDev != NULL){
            ///do acl disconnect
            ME_ForceDisconnectLinkWithReason(NULL,user_bt_env.dev[dev_index].remDev,BEC_USER_TERMINATED,TRUE); 
        }
        else{
//            status = ME_ForceCancelCreateLink();
            status = CMGR_RemoveDataLink(handler);
        }
        
//        if(status != BT_STATUS_PENDING){
//            ///no acl connection,just reset the state
//            for(uint8_t i = 0; i < NUM_BT_DEVICES; i++){
//                if(hf_channel[i].state == HF_STATE_CONN_PENDING){
//                    hf_channel[i].state = HF_STATE_CLOSED;
//                    hf_channel[i].flags = 0;
//                }            
//            }
//        }

    }
    else{
        if(user_bt_env.dev[dev_index].conFlags & LINK_STATUS_SCO_CONNECTED){
            HF_DisconnectAudioLink(user_bt_env.dev[dev_index].hf_chan);
         }
        if(user_bt_env.dev[dev_index].hf_chan->state != HF_STATE_CLOSED){
            HF_DisconnectServiceLink(user_bt_env.dev[dev_index].hf_chan);
        }
        if(user_bt_env.dev[dev_index].hfg_chan->state != HFG_STATE_CLOSED){
            HFG_DisconnectServiceLink(user_bt_env.dev[dev_index].hfg_chan);
        }
        if(user_bt_env.dev[dev_index].rcp_chan->chnl.conn.state != 0){
            AVRCP_Disconnect(user_bt_env.dev[dev_index].rcp_chan);
        }
        if(user_bt_env.dev[dev_index].pstream->stream.state != 0){
            A2DP_CloseStream(user_bt_env.dev[dev_index].pstream);
        }    
        if(user_bt_env.dev[dev_index].pbap_client != NULL){
            PBAP_ClientDisconnect(user_bt_env.dev[dev_index].pbap_client);
        }
    }
    return status;
}

//BtStatus bt_connect_internal(uint8_t dev_index)
//{
//    BtStatus status;
//    if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_CONNECTING){
//        if(user_bt_env.connect_param.connect_times > 0){
//            user_bt_env.connect_param.connect_times --;
//            status = bt_connect_according_to_profile(&user_bt_env.dev[dev_index].remote_bd,user_bt_env.enable_profiles);
//        }
//        else{
//            status =  BT_STATUS_TIMEOUT;
//        }
//    }
//    else{
//        status =  BT_STATUS_INVALID_PARM;
//    }
//    printf("connect internal %d,%d\r\n",user_bt_env.connect_param.connect_times,status);
//    if(status != BT_STATUS_PENDING){
//        user_bt_env.connect_param.connect_times = 0;
//        user_bt_env.dev[dev_index].state = BT_LINK_STATE_IDLE;
//        memset(&user_bt_env.dev[dev_index].remote_bd,0,sizeof(BD_ADDR));
//    }
//    return status;
//}

void bt_disconnect_cb(BD_ADDR *addr, uint8_t errcode)
{
    BtStatus status;
    if(errcode == BEC_CONNECTION_TIMEOUT){
        //linkloss, auto reconnect in hf mode
//        user_bt_env.connect_times = MAX_RECONNECT_TIMES;
//        status = bt_connect(addr);
        uint8_t dev_index = bt_find_dev_index(addr);
        user_bt_env.connect_times = MAX_RECONNECT_TIMES;
        memcpy(&user_bt_env.last_dev_addr,addr,BD_ADDR_SIZE);
        printf("linkloss>>%d,%x\r\n",dev_index,user_bt_env.dev[dev_index].connect_profile);
        xTimerChangePeriod(bt_linkloss_connect_timer, 10000, portMAX_DELAY);
        vTimerSetTimerID(bt_linkloss_connect_timer,(void *)(uint32_t)user_bt_env.dev[dev_index].connect_profile);
        xTimerStart(bt_linkloss_connect_timer,portMAX_DELAY);
    }
    else if(errcode == BEC_USER_TERMINATED){
    
    }
    else if(errcode == BEC_LOCAL_TERMINATED){
    
    }
    else{
    
    }
       
}

void bt_connect_timer_cb(TimerHandle_t pxTimer)
{
    printf("bt connect timer cb\r\n");
    if(user_bt_env.connect_times > 0){
        user_bt_env.connect_times --;
        bt_connect(&user_bt_env.last_dev_addr, user_bt_env.last_connect_profile);
    }
}

void bt_avrcp_connect_timer_cb(TimerHandle_t pxTimer)
{   
    BtStatus status;
    printf("bt avrcp connect timer cb\r\n");

    uint8_t dev_index = (uint32_t)pvTimerGetTimerID(bt_avrcp_connect_timer);
    if(((user_bt_env.dev[dev_index].conFlags&LINK_STATUS_AVC_CONNECTED) == 0)
      && ((user_bt_env.dev[dev_index].conFlags&LINK_STATUS_AV_CONNECTED) == LINK_STATUS_AV_CONNECTED)){
        uint8_t index = bt_get_free_avrcp_channel();
        status = AVRCP_Connect(&rcpCtChannel[index],&user_bt_env.dev[dev_index].remote_bd);
        printf("avrcp connect status = %d\r\n",status);
    }
}

void bt_a2dp_connect_timer_cb(TimerHandle_t pxTimer)
{   
    BtStatus status;
    printf("bt a2dp connect timer cb\r\n");

    uint8_t dev_index = (uint32_t)pvTimerGetTimerID(bt_a2dp_connect_timer);
    if(((user_bt_env.dev[dev_index].conFlags&LINK_STATUS_AV_CONNECTED) == 0)
      && ((user_bt_env.dev[dev_index].conFlags&LINK_STATUS_HFG_CONNECTED) == LINK_STATUS_HFG_CONNECTED)){
        uint8_t index = bt_get_free_a2dp_source_stream();
        if(index < NUM_STREAMS){
            A2DP_OpenStream(&Stream[index], &user_bt_env.dev[dev_index].remote_bd);    
        }    
        printf("a2dp connect status = %d\r\n",status);
    }
}

void bt_linkloss_connect_timer_cb(TimerHandle_t pxTimer)
{
    printf("bt linkloss timer cb\r\n");
    uint8_t profiles = (uint32_t)pvTimerGetTimerID(bt_linkloss_connect_timer);
    bt_connect(&user_bt_env.last_dev_addr, profiles);
}

void bt_connect_cb(uint8_t type, BD_ADDR *addr, uint8_t errcode)
{
//    printf("bt connect cb:type = %d,addr=0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,err=%d\r\n",\
//            type,addr->A[0],addr->A[1],addr->A[2],addr->A[3],addr->A[4],addr->A[5],errcode);

    if((type == BT_EVENT_CON_CNF) && (errcode == BEC_PAGE_TIMEOUT) && (user_bt_env.connect_times > 0)){

        memcpy(&user_bt_env.last_dev_addr,addr,BD_ADDR_SIZE);
        xTimerStart(bt_connect_timer,portMAX_DELAY);
    }
}

static void bt_free_elt(void)
{
    struct bt_connect_elt_t *elt;
    GLOBAL_INT_DISABLE();
    elt = (struct bt_connect_elt_t *)co_list_pop_front(&user_bt_env.op_list);
    if(elt){
        user_bt_env.cur_action = BT_ACTION_NULL;
        user_bt_env.action_cnt --;
        btdm_free((void *)elt);
    }
    GLOBAL_INT_RESTORE();
}

uint8_t  bt_check_conn(uint8_t dev_index)
{
    uint16_t conn_flag = 0;
    uint16_t conn_flag_tmp;
    uint8_t ret = false;
    if(user_bt_env.enable_profiles & ENABLE_PROFILE_HF){
        conn_flag |= LINK_STATUS_HF_CONNECTED;
    }
    if(user_bt_env.enable_profiles & (ENABLE_PROFILE_A2DP_SINK | ENABLE_PROFILE_A2DP_SOURCE)){
        conn_flag |= LINK_STATUS_AV_CONNECTED | LINK_STATUS_AVC_CONNECTED;
    }
    if(user_bt_env.enable_profiles & ENABLE_PROFILE_HFG){
        conn_flag |= LINK_STATUS_HFG_CONNECTED;
    }
    
    if((conn_flag & (LINK_STATUS_HF_CONNECTED|LINK_STATUS_HFG_CONNECTED)) == (LINK_STATUS_HF_CONNECTED|LINK_STATUS_HFG_CONNECTED)){
        ///both supported,only check one profile
        conn_flag_tmp = conn_flag & (~LINK_STATUS_HF_CONNECTED);
        if((user_bt_env.dev[dev_index].conFlags & conn_flag_tmp) == conn_flag_tmp){
            ret = true;
        }
        conn_flag_tmp = conn_flag & (~LINK_STATUS_HFG_CONNECTED);
        if((user_bt_env.dev[dev_index].conFlags & conn_flag_tmp) == conn_flag_tmp){
            ret = true;
        }
    }
    else if((user_bt_env.dev[dev_index].conFlags & conn_flag) == conn_flag){
        ret = true;
    }
    printf("bt check conn flag = %x,profile=%x,conn_flg=%x,ret=%d\r\n",user_bt_env.dev[dev_index].conFlags,user_bt_env.enable_profiles,conn_flag,ret);

    return ret;
}

void bt_update_conn_status(uint8_t event, void *chan, const void *param)
{
    uint8_t dev_index;
    BD_ADDR addr;
    BtRemoteDevice *rm_dev = NULL;
    BtStatus status;
    extern uint8_t g_volume_level; // 添加extern声明
    //HfCallbackParms *info;
    
    //printf("event %d\r\n",event);
    if(event < BT_PROFILE_HF_MAX){
//        info = (HfCallbackParms *)param;
        if((event == BT_PROFILE_HF_CONN_REQ) || (event == BT_PROFILE_HF_CONN)){
            rm_dev = ((HfCallbackParms *)param)->p.remDev;
            dev_index = bt_find_dev_index_by_dev(rm_dev);
        }
        else{
            dev_index = bt_find_dev_index_by_hfchan(chan);
        } 
    }
    else if(event < BT_PROFILE_A2DP_MAX){
        if(event == BT_PROFILE_A2DP_DISCONN){
            A2dpCallbackParms *pm = (A2dpCallbackParms *)param;
            rm_dev = pm->p.device;
            if(rm_dev == NULL){
                rm_dev = A2DP_GetRemoteDevice((A2dpStream *)chan);
            }
            dev_index = bt_find_dev_index_by_dev(rm_dev);
        }
        else{
            rm_dev = A2DP_GetRemoteDevice((A2dpStream *)chan);
            dev_index = bt_find_dev_index_by_dev(rm_dev);
        }
    }
    else if(event < BT_PROFILE_AVRCP_MAX){
        if((event == BT_PROFILE_AVRCP_CONN) || (event == BT_PROFILE_AVRCP_DISCONN)){
            rm_dev = ((AvrcpCallbackParms *)param)->p.remDev;
            dev_index = bt_find_dev_index_by_dev(rm_dev);
        }
        else{
            dev_index = bt_find_dev_index_by_rcpchan(chan);
        } 
    }
    else if(event < BT_PROFILE_PBAP_MAX){
        dev_index = bt_find_dev_index_by_pbapclient(((PbapClientCallbackParms *)param)->client);
    }
    else if(event < BT_PROFILE_HFG_MAX){
        if(event == BT_PROFILE_HFG_AUDIO_DATA){
            dev_index = bt_find_dev_index_by_hfgchan(chan);
        }
        else{
        rm_dev = ((HfgCallbackParms *)param)->p.remDev;
        dev_index = bt_find_dev_index_by_dev(rm_dev);
    }
    }
    else if(event < BT_INFO_MAX){
        dev_index = 0;
    }
    if(dev_index >= NUM_BT_DEVICES){
        printf("!!!!error dev index, event = %d,%x,%x\r\n",event,(unsigned int)rm_dev,(unsigned int)user_bt_env.dev[0].remDev);
        return;
    }
    //printf("bt update conn %d\r\n",event);
    switch(event){
        case BT_PROFILE_HF_CONN_REQ:
            user_bt_env.dev[dev_index].responder = TRUE;
            user_bt_env.dev[dev_index].hf_chan = chan;
        break;
        
        case BT_PROFILE_HF_CONN:
        {
            user_bt_env.dev[dev_index].hf_chan = chan;
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_HF_CONNECTED;
            
            ///check connection
            if(true == bt_check_conn(dev_index)){
                bt_connect_act_cmp(BT_EVENT_PROFILE_CONNECT,0,rm_dev);
            }
            
            ///enable voltage notify
            bt_send_hf_cmd(dev_index,hf_enable_voltage_notify);
            
            ///search remote device type
            bt_send_hf_cmd(dev_index,hf_search_remote_dev_type);
            
            ///connect a2dp in master role
            if((user_bt_env.dev[dev_index].responder == FALSE)
                && ((user_bt_env.dev[dev_index].conFlags & LINK_STATUS_AV_CONNECTED) == 0)
                && (user_bt_env.enable_profiles & ENABLE_PROFILE_A2DP_SINK))
            {
                    uint8_t index = bt_get_free_a2dp_sink_stream();
                    status = A2DP_OpenStream(&Stream[index],&user_bt_env.dev[dev_index].remote_bd);
                    printf("a2dp open stream status=%d\r\n",status);
            }

        }
        break;
    
        case BT_PROFILE_HF_DISCONN:
        {
//            ME_GetBdAddr(info->p.remDev, addr);
//            dev_index = bt_find_dev_index(addr);
//            HfCallbackParms *info = (HfCallbackParms *)param;
//            dev_index = bt_find_dev_index_by_dev(info->p.remDev);
            user_bt_env.dev[dev_index].hf_chan = NULL;
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_HF_CONNECTED;
        }
        break;
        case BT_PROFILE_HF_CALL:
        {
            user_bt_env.dev[dev_index].active = ((HfCallbackParms *)param)->p.call;
        }
        break;
        case BT_PROFILE_HF_CALLSETUP:
        {
            user_bt_env.dev[dev_index].setup_state =((HfCallbackParms *)param)->p.callSetup;
        }
        break;
        case BT_PROFILE_HF_AUDIO_CONN:
        {
            system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_SCO_ONGOING);
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_SCO_CONNECTED;
            #ifdef ENABLE_AUDIO_TRANSFER
            /* connecting phone and earpods case*/
            if((NUM_BT_DEVICES == 2)&&(user_bt_env.dev[!dev_index].conFlags & LINK_STATUS_HFG_CONNECTED)){
                HFG_CreateAudioLink(user_bt_env.dev[!dev_index].hfg_chan, HFG_AR_LOCAL_USER_ACTION);
            }
            #endif
        }
        break;
        case BT_PROFILE_HF_AUDIO_DISCONN:
        {
            system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_SCO_ONGOING);
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_SCO_CONNECTED;
            printf("hfg conflags = %x\r\n",user_bt_env.dev[!dev_index].conFlags);
            #ifdef ENABLE_AUDIO_TRANSFER
            /* connecting phone and earpods case*/
            if((NUM_BT_DEVICES == 2) && (user_bt_env.dev[!dev_index].conFlags & LINK_STATUS_SCO_CONNECTED)){
                HFG_DisconnectAudioLink(user_bt_env.dev[!dev_index].hfg_chan, HFG_AR_LOCAL_USER_ACTION);
            }     
            #endif
        }
        break;
        case BT_PROFILE_HF_AT_RESULT:
        {
            HfAtData *atdata = (HfAtData *)(((HfCallbackParms *)param)->p.data);
            printf("at result:");
            for(uint8_t i = 0; i < atdata->dataLen; i++)
            {
                printf("%c",atdata->data[i]);
            }            
            printf("\r\n");
        }
        break;
        case BT_PROFILE_HF_AUDIO_DATA:
        {
            #ifdef ENABLE_AUDIO_TRANSFER
            memcpy(voice_phone_data,((HfCallbackParms*)param)->p.audioData->data,((HfCallbackParms*)param)->p.audioData->len);
            
            BtPacket *sco_packet;
            sco_packet = btdm_malloc(sizeof(BtPacket));
            memset((void *)sco_packet, 0, sizeof(BtPacket));
            sco_packet->data = btdm_malloc(120);
            memcpy(sco_packet->data, voice_headset_data, ((HfCallbackParms*)param)->p.audioData->len);
            sco_packet->dataLen = ((HfCallbackParms*)param)->p.audioData->len;
            status = HF_SendAudioData((HfChannel *)chan, sco_packet);
            if(status != BT_STATUS_PENDING){
                printf("no pending:%d\r\n",status);
                btdm_free((void *)sco_packet->data);
                btdm_free((void *)sco_packet);
            } 
            #endif
        }
        break;
        case BT_PROFILE_HF_SPK_VOL:
        {
            printf("HF SPK VOLUME: %d\r\n",((HfCallbackParms *)param)->p.gain);
        }
        break;
        case BT_PROFILE_HF_CURRENT_CALL:
        {
            const char *number = ((HfCallbackParms *)param)->p.callListParms->number;
            printf("current call number: ");
            for(uint8_t i = 0; i < strlen(number); i++)
            {
                printf("%c ",number[i]);
            }
            printf("\r\n");
        }
        break;
        case BT_PROFILE_A2DP_OPEN_IND:
        {
            user_bt_env.dev[dev_index].responder = TRUE;
        }
        break;
        
        case BT_PROFILE_A2DP_CONN:
        {
            //printf("=== A2DP CONNECTION CALLBACK STARTED ===\n");
            user_bt_env.dev[dev_index].pstream = chan;
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_AV_CONNECTED;
            //printf("A2DP CONNECTION SUCCESS! dev_index=%d\n", dev_index);
            
            //printf("DEBUG: Checking connection status...\n");
            if(true == bt_check_conn(dev_index)){
                //printf("DEBUG: Connection check passed\n");
                bt_connect_act_cmp(BT_EVENT_PROFILE_CONNECT,0,rm_dev);
            }
            //printf("DEBUG: AVRCP timer check...\n");
            if(((user_bt_env.dev[dev_index].conFlags&LINK_STATUS_AVC_CONNECTED) == 0)
              && (user_bt_env.dev[dev_index].responder == FALSE)){
                //printf("DEBUG: Starting AVRCP timer\n");
                vTimerSetTimerID(bt_avrcp_connect_timer,(void *)(uint32_t)dev_index);
                xTimerStart(bt_avrcp_connect_timer,portMAX_DELAY);
            }
              
            printf("DEBUG: Processing codec info...\n");
            AvdtpConfigRequest *req = ((A2dpCallbackParms *)param)->p.configReq;
            bt_save_codec_info(dev_index, &req->codec.elements[0]);
            printf("a2dp connected.%d\r\n",dev_index);
            printf("a2dp conn: %d,%x,%x,%x,%x\r\n",req->codec.codecType,req->codec.elements[0],req->codec.elements[1],req->codec.elements[2],req->codec.elements[3]);
            
            printf("DEBUG: Parsing SBC configuration...\n");
            // 解析SBC配置并确定采样率
            uint32_t sample_rate = 44100; // 默认采样率
            uint8_t sbc_config = req->codec.elements[0];
            
            if(sbc_config & 0x20) {
                sample_rate = 44100;
            } else if(sbc_config & 0x10) {
                sample_rate = 48000;
            } else if(sbc_config & 0x40) {
                sample_rate = 32000;
            } else if(sbc_config & 0x80) {
                sample_rate = 16000;
            }
            
            printf("SBC config: 0x%02X, sample_rate=%d\n", sbc_config, sample_rate);
            
            printf("DEBUG: Preventing sleep...\n");
            // 强制禁止系统休眠，确保音频播放正常
            app_audio_force_prevent_sleep();
            printf("A2DP connected - sleep prevented for audio playback\n");
            
            printf("DEBUG: Initializing audio hardware...\n");
            // 立即初始化音频硬件
            printf("Initializing audio hardware for A2DP...\n");
            extern void audio_hw_init(uint32_t sample_rate);
            audio_hw_init(sample_rate);
            
            printf("DEBUG: Starting A2DP sink...\n");
            // 创建A2DP音频场景
            app_audio_a2dp_sink_start(AUDIO_TYPE_SBC, sample_rate);
            
            printf("DEBUG: Audio setup completed\n");
            // 播放测试音验证DAC工作
            printf("Playing test tone to verify DAC...\n");
            // app_audio_play_test_tone(); // 已删除的函数
            printf("A2DP audio setup completed\n");
            
            // 添加用户提示
            printf("=== A2DP CONNECTED SUCCESSFULLY ===\n");
            printf("Please start playing music on your phone now!\n");
            printf("Audio hardware is ready and waiting for data...\n");
            printf("=====================================\n");
            
            printf("DEBUG: A2DP connection callback completed\n");
        }
        break;
        
        case BT_PROFILE_A2DP_DISCONN:
        {
            user_bt_env.dev[dev_index].pstream = NULL;
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_AV_CONNECTED;
            printf("a2dp disconnected.%d\r\n",dev_index);

            #ifdef ENABLE_AUDIO_TRANSFER
            if((user_bt_env.dev[!dev_index].conFlags & LINK_STATUS_MEDIA_PLAYING)){
                /* connecting phone and earpods case*/
                ME_SetLinkPolicy(user_bt_env.dev[!dev_index].remDev,BLP_MASTER_SLAVE_SWITCH|BLP_SNIFF_MODE);
                A2DP_SuspendStream(user_bt_env.dev[!dev_index].pstream);
            }
            #endif
            
            // 停止A2DP音频场景
            app_audio_a2dp_sink_stop();
            
            // 允许系统休眠
            app_audio_allow_sleep();
            printf("A2DP disconnected - sleep allowed\n");
            
            system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
            app_dac_pa_ctrl(0); // 关闭功放
        }
        break;
        
        case BT_PROFILE_A2DP_PLAYING:
        {
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_MEDIA_PLAYING;
            printf("A2DP PLAYING STARTED! dev_index=%d\n", dev_index);
            system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
            #ifdef ENABLE_AUDIO_TRANSFER
            /* connecting phone and earpods case*/
            if((user_bt_env.dev[!dev_index].conFlags & LINK_STATUS_AV_CONNECTED)){
                ME_SetLinkPolicy(user_bt_env.dev[!dev_index].remDev,BLP_MASTER_SLAVE_SWITCH);//disable sniff
                A2DP_StartStream(user_bt_env.dev[!dev_index].pstream);
            }    
            #endif
        }
        break;
        
        case BT_PROFILE_A2DP_SUSPEND:
        {
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_MEDIA_PLAYING;
            system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
            #ifdef ENABLE_AUDIO_TRANSFER
            /* connecting phone and earpods case*/
            if((user_bt_env.dev[!dev_index].conFlags & LINK_STATUS_MEDIA_PLAYING)){
                ME_SetLinkPolicy(user_bt_env.dev[!dev_index].remDev,BLP_MASTER_SLAVE_SWITCH|BLP_SNIFF_MODE);
                A2DP_SuspendStream(user_bt_env.dev[!dev_index].pstream);
            }
            #endif

        }
        break;
        case BT_PROFILE_A2DP_STREAM_DATA:
        {
            // 注释掉A2DP数据包频率统计
            // static uint32_t a2dp_pkt_count = 0;
            // static uint32_t a2dp_last_time = 0;
            // static uint32_t a2dp_pkt_per_sec = 0;
            
            // a2dp_pkt_count++;
            // uint32_t current_time = xTaskGetTickCount() * portTICK_PERIOD_MS;
            
            // if (current_time - a2dp_last_time >= 1000) { // 每秒统计一次
            //     a2dp_pkt_per_sec = a2dp_pkt_count;
            //     a2dp_pkt_count = 0;
            //     a2dp_last_time = current_time;
                
            //     // 理论A2DP包频率计算
            //     // SBC帧长度 = 4 + ((4*numSubBands*numChannels)>>3) + ((numBlocks*bitPool + numSubBands)>>3)
            //     // 对于44.1kHz, 16blocks, 8subbands, 53bitpool, 2channels
            //     // 理论帧长度 = 4 + ((4*8*2)>>3) + ((16*53 + 8)>>3) = 4 + 8 + 107 = 119字节
            //     // 理论包频率 = 44100 / (16*8) = 344.5包/秒
            //     uint32_t theoretical_pkts_per_sec = 44100 / (16 * 8); // 简化计算，使用固定采样率
                
            //     printf("A2DP STATS: received=%d pkts/sec, theoretical=%d pkts/sec, sample_rate=44100\n", 
            //            a2dp_pkt_per_sec, theoretical_pkts_per_sec);
            // }
            
            // 只保留关键的A2DP数据接收信息
            static uint32_t a2dp_data_count = 0;
            a2dp_data_count++;
            if (a2dp_data_count % 1000 == 0) { // 从100增加到1000，减少打印频率
                printf("A2DP_PROBE: data received - count=%d, length=%d\r\n", 
                       a2dp_data_count, ((A2dpCallbackParms *)param)->len);
            }
            
            #ifdef ENABLE_AUDIO_TRANSFER
            if(user_bt_env.dev[!dev_index].conFlags & LINK_STATUS_MEDIA_PLAYING)
            {
                BtStatus status;
//                uint16_t temp = (1*sbcinfo[dev_index].info.numSubBands) + (sbcinfo[dev_index].info.numBlocks*sbcinfo[dev_index].info.bitPool);
//                uint16_t frame_len = 4 + ((4*sbcinfo[dev_index].info.numSubBands*sbcinfo[dev_index].info.numChannels)>>3) + (temp>>3);
//                if(temp%8){
//                    frame_len++;
//                }         
                uint16_t frame_len = sbc_calc_frame_len(&sbcinfo[dev_index]);
                
//                printf("send frame len=%d\r\n",frame_len);
                if(user_bt_env.bt_source_sbc_pkt_num < 10){
                    A2dpSbcPacket *packet = (A2dpSbcPacket *)btdm_malloc(sizeof(A2dpSbcPacket));
                    packet->frameSize = frame_len;
                    packet->dataLen = ((A2dpCallbackParms *)param)->len - 13;
                    packet->data = (uint8_t *)btdm_malloc(packet->dataLen);
                    memcpy(packet->data,((A2dpCallbackParms *)param)->p.data + 13,packet->dataLen);
                    status = A2DP_StreamSendSbcPacket(user_bt_env.dev[!dev_index].pstream,packet,&sbcinfo[!dev_index].info);
                    
                    if(status != BT_STATUS_PENDING){
                        printf("err sending sbc data\r\n");
                        btdm_free(packet->data);
                        btdm_free(packet);
                    }
                    else{
                        user_bt_env.bt_source_sbc_pkt_num ++;
                    }
                }
            }
            #endif
            
            // 使用任务队列处理SBC解码，避免在回调中耗时操作
            uint8_t *audio_data = ((A2dpCallbackParms *)param)->p.data + 13;
            uint32_t audio_len = ((A2dpCallbackParms *)param)->len - 13;
            // 注释掉本地音频播放信息
            // printf("Local audio playback: data_len=%d, data[0]=0x%02X\n", audio_len, audio_data[0]);
            
            // 发送SBC数据到解码任务队列
            if (!send_sbc_data_to_decode_task(audio_data, audio_len)) {
                printf("A2DP_PROBE: failed to send SBC data to decode task\r\n");
            }
            
            // 注释掉音频播放状态设置
            // audio_set_playing_state(true);
        }    
        break;
        case BT_PROFILE_A2DP_SBC_PKT_SENT:
            btdm_free(((A2dpCallbackParms *)param)->p.sbcPacket->data);
            btdm_free(((A2dpCallbackParms *)param)->p.sbcPacket);
            user_bt_env.bt_source_sbc_pkt_num--;
        break;
        case BT_PROFILE_AVRCP_CONN:
        {
            user_bt_env.dev[dev_index].rcp_chan = chan;
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_AVC_CONNECTED;
            if(true == bt_check_conn(dev_index)){
                bt_connect_act_cmp(BT_EVENT_PROFILE_CONNECT,0,rm_dev);
            }
        }
        break;
        
        case BT_PROFILE_AVRCP_DISCONN:
        {
            user_bt_env.dev[dev_index].rcp_chan = NULL;
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_AVC_CONNECTED;
        }
        break;
        
        case BT_PROFILE_AVRCP_EVENT_SUPPORT:
        {
            uint16_t *event_mask = (uint16_t *)param;
            uint16_t event_sup = (*event_mask) & (AVRCP_ENABLE_PLAY_STATUS_CHANGED|AVRCP_ENABLE_TRACK_CHANGED);
            if(user_bt_env.dev[dev_index].connect_profile&ENABLE_PROFILE_A2DP_SINK){
                bt_avrcp_register_notification(chan,event_sup);
            }
            else{
                bt_avrcp_register_notification(chan,AVRCP_ENABLE_VOLUME_CHANGED);
            }
        }
        break;
        
        case BT_PROFILE_AVRCP_MEDIA_STATUS:
        {
            uint8_t *media_status = (uint8_t *)param;
            if((*media_status == AVRCP_MEDIA_PAUSED) || (*media_status == AVRCP_MEDIA_STOPPED)){
                printf("media paused\r\n");
                user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_MEDIA_PLAYING;
            }
            else{
                printf("media playing\r\n");
                user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_MEDIA_PLAYING;
            }
        }
        break;
        
        case BT_PROFILE_PBAP_CONN:
        {
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_PBAP_CONNECTED;
        }    
        break;
        
        case BT_PROFILE_PBAP_DISCONN:
        {
            user_bt_env.dev[dev_index].pbap_client = NULL;
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_PBAP_CONNECTED;
        }    
        break;
        
        case BT_PROFILE_PBAP_DATA_IND:
        {
            printf("data ind: \r\n");
            for(uint16_t i = 0; i < ((PbapClientCallbackParms *)param)->u.dataInd.len; i++)
            {
                printf("%c",((PbapClientCallbackParms *)param)->u.dataInd.buffer[i]);
            }
            printf("\r\n");
        }    
        break;
        
        case BT_PROFILE_PBAP_COMP:
            
        break;
        case BT_PROFILE_HFG_CONN_REQ:
            user_bt_env.dev[dev_index].responder = TRUE;
        break;
        case BT_PROFILE_HFG_CONN:
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_HFG_CONNECTED;
            user_bt_env.dev[dev_index].hfg_chan = chan;
        
            ///check connection
            if(true == bt_check_conn(dev_index)){
                bt_connect_act_cmp(BT_EVENT_PROFILE_CONNECT,0,rm_dev);
            }
            
            if(((user_bt_env.dev[dev_index].conFlags & LINK_STATUS_AV_CONNECTED) == 0)
                && (user_bt_env.enable_profiles & ENABLE_PROFILE_A2DP_SOURCE)){
                if(user_bt_env.dev[dev_index].responder == FALSE){
                uint8_t index = bt_get_free_a2dp_source_stream();
                if(index < NUM_STREAMS){
                    A2DP_OpenStream(&Stream[index], &user_bt_env.dev[dev_index].remote_bd);    
                }
            }
                else{
                    printf("...start a2dp timer\r\n");
                    vTimerSetTimerID(bt_a2dp_connect_timer,(void *)(uint32_t)dev_index);
                    xTimerStart(bt_a2dp_connect_timer,portMAX_DELAY);
                }
            }
        break;
        case BT_PROFILE_HFG_DISCONN:
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_HFG_CONNECTED;
            user_bt_env.dev[dev_index].hfg_chan = NULL;
        break;
        
        case BT_PROFILE_HFG_AUDIO_CONN:
        {
            ///disable sniff
            ME_SetLinkPolicy(user_bt_env.dev[dev_index].remDev,BLP_MASTER_SLAVE_SWITCH);
            user_bt_env.dev[dev_index].conFlags |= LINK_STATUS_SCO_CONNECTED;
        }
        break;
        
        case BT_PROFILE_HFG_AUDIO_DISCONN:
        {
            ///enable sniff
            ME_SetLinkPolicy(user_bt_env.dev[dev_index].remDev,BLP_MASTER_SLAVE_SWITCH|BLP_SNIFF_MODE);
            user_bt_env.dev[dev_index].conFlags &= ~LINK_STATUS_SCO_CONNECTED;
        }
        break;
        case BT_PROFILE_HFG_AUDIO_DATA:
//                BtPacket *sco_packet;
//                sco_packet = btdm_malloc(sizeof(BtPacket));
//                sco_packet = btdm_malloc(sizeof(BtPacket));
//                memset((void *)sco_packet, 0, sizeof(BtPacket));
//                sco_packet->data = btdm_malloc(120);
//                memcpy(sco_packet->data, Info->p.audioData->data, Info->p.audioData->len);
//                sco_packet->dataLen = Info->p.audioData->len;
//                status = HF_SendAudioData(Chan, sco_packet);
//                if(status != BT_STATUS_PENDING){
//                    printf("no pending:%d\r\n",status);
//                    btdm_free((void *)sco_packet->data);
//                    btdm_free((void *)sco_packet);
//                }                
        
        {
            #ifdef ENABLE_AUDIO_TRANSFER
            BtPacket *sco_packet;
            sco_packet = btdm_malloc(sizeof(BtPacket));
            memset((void *)sco_packet, 0, sizeof(BtPacket));
            sco_packet->data = btdm_malloc(120);
            memcpy(sco_packet->data, voice_phone_data, ((HfCallbackParms*)param)->p.audioData->len);
            memcpy(voice_headset_data, ((HfCallbackParms*)param)->p.audioData->data, ((HfCallbackParms*)param)->p.audioData->len);
            ///loopback
            sco_packet->dataLen = ((HfCallbackParms*)param)->p.audioData->len;
            status = HFG_SendAudioData((HfgChannel *)chan, sco_packet);
            if(status != BT_STATUS_PENDING){
                printf("no pending:%d\r\n",status);
                btdm_free((void *)sco_packet->data);
                btdm_free((void *)sco_packet);
            } 
            #endif
        }        
        break;
        case BT_INFO_INQ_RESULT:
        {
            BtInquiryResult    *inqResult = (BtInquiryResult *)param;
            uint8_t name[MAX_NAME_SIZE];
            uint8_t len;
            printf("inq result: %x\r\n",inqResult->classOfDevice);
            printf("addr:0x%02x%02x%02x%02x%02x%02x\r\n",inqResult->bdAddr.A[0],inqResult->bdAddr.A[1],inqResult->bdAddr.A[2],
                    inqResult->bdAddr.A[3],inqResult->bdAddr.A[4],inqResult->bdAddr.A[5]);
            printf("rssi:%d,name: ",inqResult->rssi);
            bt_parse_inq_result((uint8_t *)inqResult->extInqResp,name,&len);   
            for(uint8_t i = 0; i < len; i++)
            {
                printf("%c",name[i]);
            }
            printf("\r\n");
            if(len == 0){
                bt_name_query(&inqResult->bdAddr, &inqResult->psi);  
            }
        }
        break;
        
        case BT_INFO_INQ_CANCEL:
        {
            printf("inquiry cancelled\r\n");
        }
        break;
        case BT_INFO_INQ_COMP:
        {
            //do inquiry again
            ME_Inquiry(BT_IAC_GIAC, 5, 5);
        }
        break;
#if 0
        case BT_PROFILE_AVRCP_VOLUME_CHANGED:
        {
            uint8_t *volume = (uint8_t *)param;
            printf("AVRCP volume changed: %d (0x%02X)\r\n", *volume, *volume);
            // 实现音量控制
            extern uint8_t g_volume_level;
            g_volume_level = *volume;
            printf("Volume control applied: level=%d\r\n", *volume);
        }
        break;
#endif
        case BT_PROFILE_AVRCP_ADV_INFO:
        {
            // 处理AVRCP高级信息事件，包括音量控制
            AvrcpCallbackParms *avrcp_parms = (AvrcpCallbackParms *)param;
            if (avrcp_parms->advOp == AVRCP_OP_SET_ABSOLUTE_VOLUME) {
                uint8_t volume = avrcp_parms->p.adv.info.volume;
                printf("AVRCP volume changed: %d (0x%02X)\r\n", volume, volume);
                
                // 实现音量控制
                // AVRCP音量范围是0-127，需要转换为DAC音量控制
                g_volume_level = volume; // 保存音量级别
                
                printf("Volume control applied: level=%d\r\n", volume);
            }
        }
        break;
        case BT_PROFILE_AVRCP_MEDIA_INFO:
        {
            uint8_t *media_info = (uint8_t *)param;
            printf("AVRCP media info: %d (0x%02X)\r\n", *media_info, *media_info);
            
            // 处理AVRCP媒体信息事件
            // 这里可以添加处理AVRCP媒体信息事件的逻辑
        }
        break;
    }
}

CmgrHandler* bt_get_cmgr_handler(uint8_t dev_index)
{
    CmgrHandler *handler = NULL;
    if(user_bt_env.dev[dev_index].hf_chan){
        handler = &user_bt_env.dev[dev_index].hf_chan->cmgrHandler;
    }
    else if(user_bt_env.dev[dev_index].hfg_chan){
        handler = &user_bt_env.dev[dev_index].hfg_chan->cmgrHandler;
    }
    else if(user_bt_env.dev[dev_index].pstream){
        handler = &user_bt_env.dev[dev_index].pstream->device->cmgrHandler;
    }
    
    return handler;
}

void bt_connect_act_cmp(uint8_t evt,uint8_t error,BtRemoteDevice *rem_dev)
{
    uint8_t dev_index;
    struct bt_connect_elt_t *elt;
    uint8_t cur_act = BT_ACTION_NULL;
    BD_ADDR *cur_addr = NULL;
    uint8_t check_op_list = false;    
    BtStatus ret;
    
    elt = (struct bt_connect_elt_t *)co_list_pick(&user_bt_env.op_list);
    if(elt){
        cur_act = elt->action;
        cur_addr = &elt->addr;
    }
    printf("bt_connect_act_cmp:evt=%d,act = %d,error=%d\r\n",evt,elt->action,error);
    switch(evt){
        case BT_EVENT_CON_IND:
        case BT_EVENT_CON_CNF:
            dev_index = bt_find_dev_index(&rem_dev->bdAddr);
            
            if(dev_index >= NUM_BT_DEVICES){
                if(evt == BT_EVENT_CON_IND){
                    dev_index = bt_get_free_dev();
                    assert(dev_index < NUM_BT_DEVICES);
                }
                else{
                    printf("shall not be here...,%s,%d\r\n",__FUNCTION__,__LINE__);
                }
            }
            printf("rem dev cod:%x\r\n",rem_dev->cod);
            if(evt == BT_EVENT_CON_IND){
                if((rem_dev->cod & 0x0400) == 0x0400){
                    user_bt_env.dev[dev_index].connect_profile = ENABLE_PROFILE_HFG|ENABLE_PROFILE_A2DP_SOURCE;
                }
                else{
                    user_bt_env.dev[dev_index].connect_profile = ENABLE_PROFILE_HF|ENABLE_PROFILE_A2DP_SINK;
                }
            }
            if(user_bt_env.bt_connect_cb){
                user_bt_env.bt_connect_cb(evt,&rem_dev->bdAddr, error);
            }
            if(error == BEC_NO_ERROR){

                user_bt_env.dev[dev_index].remDev = rem_dev;
                user_bt_env.dev[dev_index].state = BT_LINK_STATE_ACL_CONNECTED;
                user_bt_env.last_active_index = dev_index;
                memcpy(&user_bt_env.dev[dev_index].remote_bd,&rem_dev->bdAddr,BD_ADDR_SIZE);
                if((memcmp(&rem_dev->bdAddr,cur_addr,BD_ADDR_SIZE) == 0)&&(cur_act == BT_ACTION_DISCONNECT)){
                    bt_do_disconnect(cur_addr,bt_get_cmgr_handler(dev_index),true);
                }
            }
            else{
                user_bt_env.dev[dev_index].state = BT_LINK_STATE_IDLE;
                memset(&user_bt_env.dev[dev_index].remote_bd,0,BD_ADDR_SIZE);
                if((cur_act == BT_ACTION_CONNECT) || (cur_act == BT_ACTION_DISCONNECT)){
                    bt_free_elt();
                    check_op_list = true;
                }
            }   

        break;           
            
        case BT_EVENT_PROFILE_CONNECT:
            dev_index = bt_find_dev_index(&rem_dev->bdAddr);
            user_bt_env.dev[dev_index].state = BT_LINK_STATE_PROFILE_CONNECTED;
            memcpy(&user_bt_env.last_dev_addr,&rem_dev->bdAddr,BD_ADDR_SIZE);

            printf("\r\nIV\r\n");
            if(user_bt_env.bt_connect_cb){
                user_bt_env.bt_connect_cb(evt,&rem_dev->bdAddr, error);
            }
            if(cur_act == BT_ACTION_CONNECT){
                bt_free_elt();
                check_op_list = true;
            }
        break;

        case BT_EVENT_DISCONNECT:
            dev_index = bt_find_dev_index(&rem_dev->bdAddr);
            user_bt_env.dev[dev_index].state = BT_LINK_STATE_IDLE;
            if(user_bt_env.bt_disconnect_cb){
                user_bt_env.bt_disconnect_cb(&rem_dev->bdAddr, error);
            }
            
            if((cur_act == BT_ACTION_DISCONNECT) || (cur_act == BT_ACTION_CONNECT)){
                bt_free_elt();
                check_op_list = true;
            }
            memset(&user_bt_env.dev[dev_index],0,sizeof(APP_DEVICE));
        break;
            
        case BT_EVENT_ACC_CHG:
            if(user_bt_env.bt_access_change_cb){
                user_bt_env.bt_access_change_cb(error);
            }
            user_bt_env.access_state = error;
            if(cur_act == BT_ACTION_ACCESS){
                bt_free_elt();
                check_op_list = true;
            }
        break;
    }

    ///check pending op list
    if(check_op_list == true){
        elt = (struct bt_connect_elt_t *)co_list_pick(&user_bt_env.op_list);
        while(elt && (check_op_list == true))
        {
            printf("check pending list act=%d,state=%d,addr0=%x\r\n",elt->action,user_bt_env.dev[0].state,user_bt_env.dev[0].remote_bd.A[0]);
            switch(elt->action){
                case BT_ACTION_CONNECT:
                {
                    dev_index = bt_find_dev_index(&elt->addr);
                    if(dev_index >= NUM_BT_DEVICES){
                        //device not exist, find free dev
                        dev_index = bt_get_free_dev();
                        if(dev_index < NUM_BT_DEVICES){
                            //get free dev, create new connection
                            void *chan;
                            ret = bt_do_connect(&elt->addr, elt->profiles, &chan);
                            if(ret == BT_STATUS_PENDING){
                                user_bt_env.cur_action = BT_ACTION_CONNECT;
                                user_bt_env.dev[dev_index].connect_profile = elt->profiles;
                                user_bt_env.last_connect_profile = elt->profiles; 
                                user_bt_env.dev[dev_index].state = BT_LINK_STATE_CONNECTING;
                                memcpy(&user_bt_env.dev[dev_index].remote_bd,&elt->addr,sizeof(BD_ADDR));
                                if(elt->profiles & ENABLE_PROFILE_HF){
                                    user_bt_env.dev[dev_index].hf_chan = chan;
                                }
                                check_op_list = false;
                            }
                            else{
                                bt_free_elt();
                            }
                        }
                        else{
                            //no free dev
                            bt_free_elt();
                        }
                    }
                    else{
                        //device exist,check device state
                        if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_PROFILE_CONNECTED){
                            //profile connected,return success
                            bt_free_elt();
                        }else{
                            check_op_list = false;
                        }
                    }
                }
                break;
                case BT_ACTION_DISCONNECT:
                {
                    dev_index = bt_find_dev_index(&elt->addr);
                    if(dev_index >= NUM_BT_DEVICES){
                        //don't find device
                        bt_free_elt();
                    }
                    else{
                        if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_PROFILE_CONNECTED){
                            //profile connected,return success
                            user_bt_env.dev[dev_index].state = BT_LINK_STATE_DISCONNECTING;
                            user_bt_env.cur_action = BT_ACTION_DISCONNECT;
                            bt_do_disconnect(&elt->addr,NULL,false);
                        }
                        //other state,just return
                        check_op_list = false;
                    }
                }
                break;
                case BT_ACTION_ACCESS:
                {
                    printf("shall not be here..error action access change.");
                    bt_free_elt();
                }
                break;
            }
            elt = (struct bt_connect_elt_t *)co_list_pick(&user_bt_env.op_list);
        }
    }    
}


void bt_access_change_cb(uint8_t mode)
{
    printf("access change cb: %d\r\n",mode);
}

BtStatus bt_connect(BD_ADDR *addr, uint8_t profiles)
{
    BtStatus ret = BT_STATUS_PENDING;
    uint8_t dev_index = 0;
    struct bt_connect_elt_t *elt;
    uint8_t add_to_list = false;
    
    printf("bt connect: %x,%x,%x\r\n",addr->A[0],addr->A[1],profiles);

    //param check
    assert(addr != NULL);
    
//    //error bt state, return failed
//    for(index = 0; index < NUM_BT_DEVICES; index++){
//        if((user_bt_env.dev[index].state == BT_LINK_STATE_CONNECTING) || (user_bt_env.dev[index].state == BT_LINK_STATE_DISCONNECTING)){
//            return BT_STATUS_FAILED;
//        }
//    }

    elt = (struct bt_connect_elt_t *)btdm_malloc(sizeof(struct bt_connect_elt_t));
    memcpy(&elt->addr,addr,BD_ADDR_SIZE);
    elt->action = BT_ACTION_CONNECT;
    if(co_list_is_empty(&user_bt_env.op_list)){
        //list empty, check device index
        dev_index = bt_find_dev_index(addr);
        if(dev_index >= NUM_BT_DEVICES){
            //not connection with the addr
            dev_index = bt_get_free_dev();
            if(dev_index >= NUM_BT_DEVICES){
                //no free device
                printf("err...dev state %d\r\n",user_bt_env.dev[0].state);
                btdm_free(elt);
                return BT_STATUS_NO_RESOURCES;
            }
        }
        printf("connect state=%d\r\n",user_bt_env.dev[dev_index].state);
        if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_IDLE){
            //idle state, do connect imediately
             void *chan;
            ret = bt_do_connect(addr,profiles,&chan);
            if(ret == BT_STATUS_PENDING){
                add_to_list = true;
                user_bt_env.cur_action = BT_ACTION_CONNECT;
                user_bt_env.dev[dev_index].state = BT_LINK_STATE_CONNECTING;
                user_bt_env.dev[dev_index].connect_profile = profiles;
                user_bt_env.last_connect_profile = profiles; 
                memcpy(&user_bt_env.dev[dev_index].remote_bd,addr,sizeof(BD_ADDR));
                if(profiles & ENABLE_PROFILE_HF){
                    user_bt_env.dev[dev_index].hf_chan = chan;
                }
                else if(profiles & ENABLE_PROFILE_HFG){
                    user_bt_env.dev[dev_index].hfg_chan = chan;
                }
                else if(profiles & (ENABLE_PROFILE_A2DP_SINK | ENABLE_PROFILE_A2DP_SOURCE)){
                    user_bt_env.dev[dev_index].pstream = chan;
                }                  
            }
            else{
                btdm_free(elt);
            }
        }
        else if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_DISCONNECTING){
            //disconnecting,usally shall not be here
            add_to_list = true;
        }
        else if((user_bt_env.dev[dev_index].state == BT_LINK_STATE_CONNECTING)
            || (user_bt_env.dev[dev_index].state == BT_LINK_STATE_ACL_CONNECTED)){
            //connecting or acl connected,just free connect elt,return pending
            btdm_free(elt);
        }
        else if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_PROFILE_CONNECTED){
            //profile connected,return success
            btdm_free(elt);
            ret = BT_STATUS_SUCCESS;
        }
    }else{
        add_to_list = true;
    }
    
    if(add_to_list == true){
        elt->profiles = profiles;
        GLOBAL_INT_DISABLE();
        co_list_push_back(&user_bt_env.op_list,&elt->hdr);
        user_bt_env.action_cnt ++;
        GLOBAL_INT_RESTORE();
    }
    
    return ret;
}

BtStatus bt_disconnect(BD_ADDR *addr, uint8_t force_disconnect) 
{
    BtStatus status = BT_STATUS_PENDING;
    uint8_t dev_index = 0;
    struct bt_connect_elt_t *elt,*cur_elt;
    uint8_t add_to_list = false;
    printf("bt disconnect\r\n");
    if(addr == NULL){
        return BT_STATUS_FAILED;
    }
    elt = (struct bt_connect_elt_t *)btdm_malloc(sizeof(struct bt_connect_elt_t));
    memcpy(&elt->addr,addr,BD_ADDR_SIZE);
    elt->action = BT_ACTION_DISCONNECT;
    
    if((co_list_is_empty(&user_bt_env.op_list)) || (force_disconnect == true)){
        dev_index = bt_find_dev_index(addr);
        printf("cur state=%d\r\n",user_bt_env.dev[dev_index].state);
        if(dev_index < NUM_BT_DEVICES){
            if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_IDLE){
                memset(&user_bt_env.dev[dev_index].remote_bd,0,sizeof(BD_ADDR));
                status = BT_STATUS_SUCCESS;
            }
            else if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_DISCONNECTING){
                add_to_list = false;
                if(force_disconnect == true){
//                    cur_elt = (struct bt_connect_elt_t *)co_list_pick(&user_bt_env.op_list);
                    bt_do_disconnect(addr,bt_get_cmgr_handler(dev_index),force_disconnect);
                }
            }
            else if((user_bt_env.dev[dev_index].state == BT_LINK_STATE_CONNECTING)
                || (user_bt_env.dev[dev_index].state == BT_LINK_STATE_ACL_CONNECTED))
            {
                add_to_list = true;
                if(force_disconnect == true){
                    GLOBAL_INT_DISABLE();
                    cur_elt = (struct bt_connect_elt_t *)co_list_pick(&user_bt_env.op_list);
                    if(cur_elt && (cur_elt->action == BT_ACTION_CONNECT)){
                        co_list_pop_front(&user_bt_env.op_list);
                        user_bt_env.action_cnt --;
                        btdm_free(cur_elt);
                    }
                    GLOBAL_INT_RESTORE();
                        user_bt_env.dev[dev_index].state = BT_LINK_STATE_DISCONNECTING;
                    status = bt_do_disconnect(addr,bt_get_cmgr_handler(dev_index),force_disconnect);
                    if(status != BT_STATUS_PENDING){
                        add_to_list = false;
                        user_bt_env.dev[dev_index].state = BT_LINK_STATE_IDLE;
                    }

                }
            }
            else if(user_bt_env.dev[dev_index].state == BT_LINK_STATE_PROFILE_CONNECTED){
                user_bt_env.dev[dev_index].state = BT_LINK_STATE_DISCONNECTING;
                bt_do_disconnect(addr,NULL,force_disconnect);
                add_to_list = true;
            }
        }
        else{
            btdm_free(elt);
            return BT_STATUS_FAILED;
        }
    }
    else{
        add_to_list = true;
    }
    
    if(add_to_list == true){
        printf("add to list\r\n");
        GLOBAL_INT_DISABLE();
        co_list_push_back(&user_bt_env.op_list,&elt->hdr);
        user_bt_env.action_cnt ++;
        GLOBAL_INT_RESTORE();
    }
    else{
        btdm_free(elt);
    }
    
    return status;
}

void user_bt_init(void)
{
    struct bt_connect_elt_t *elt;

    while(!co_list_is_empty(&user_bt_env.op_list)){
        user_bt_env.action_cnt --;
        elt = (struct bt_connect_elt_t *)co_list_pop_front(&user_bt_env.op_list);
        btdm_free((void *)elt);
    }
    memset((void *)&user_bt_env,0,sizeof(struct user_bt_env_t));
    co_list_init(&user_bt_env.op_list);
    user_bt_env.bt_disconnect_cb = bt_disconnect_cb;
    user_bt_env.bt_connect_cb = bt_connect_cb;
    user_bt_env.bt_access_change_cb = bt_access_change_cb;
    user_bt_env.enable_profiles = ENABLE_PROFILE_HFG | ENABLE_PROFILE_A2DP_SINK | ENABLE_PROFILE_HF | ENABLE_PROFILE_A2DP_SOURCE ;
    user_bt_env.enable_local_ring = false;
    user_bt_env.connect_times = MAX_RECONNECT_TIMES;
    user_bt_env.page_timeout = PAGE_TIMEOUT;
    ME_SetPageTimeout(user_bt_env.page_timeout);
    
#ifdef ENABLE_AUDIO_TRANSFER
    CMGR_SetAudioVoiceSettings(0x60);
    #if BTDM_STACK_ENABLE_AG
    ///only support cvsd
    HFG_SetSupportedFeature(HFG_SDK_FEATURES&~HFG_FEATURE_CODEC_NEGOTIATON);
    #endif
    #if BTDM_STACK_ENABLE_HF
    HF_SetSupportedFeature(HF_SDK_FEATURES&~HF_FEATURE_CODEC_NEGOTIATION_CFG);
    #endif
#endif
    
    for (uint8_t i=0; i<NUM_BT_DEVICES; i++) {
        sbcinfo[i].info.allocMethod = 1; //1--loudness, 2-- snr
        sbcinfo[i].info.sampleFreq = 2; // 0--16k, 1--32k, 2--44.1k, 3--48k
        sbcinfo[i].info.bitPool = 0x35;
        sbcinfo[i].info.channelMode = 3; // 0--mono, 1-- dual_chal, 2--stereo, 3--joint stereo
        sbcinfo[i].info.numBlocks = 16;
        sbcinfo[i].info.numChannels = 2;
        sbcinfo[i].info.numSubBands = 8;
        sbcinfo[i].elem[0] = 0x21;
        sbcinfo[i].elem[1] = 0x15;
        sbcinfo[i].elem[2] = 0x02;
        sbcinfo[i].elem[3] = 0x35;

    }     
    if(bt_connect_timer == NULL){
        bt_connect_timer = xTimerCreate("bt_connect_timer", 10, pdFALSE, 0, bt_connect_timer_cb );
    }

    if(bt_avrcp_connect_timer == NULL){
        bt_avrcp_connect_timer = xTimerCreate("bt_avrcp_connect_timer", 500, pdFALSE, 0, bt_avrcp_connect_timer_cb );
    }
    
    if(bt_a2dp_connect_timer == NULL){
        bt_a2dp_connect_timer = xTimerCreate("bt_a2dp_connect_timer", 4000, pdFALSE, 0, bt_a2dp_connect_timer_cb );
    }
        
    if(bt_linkloss_connect_timer == NULL){
        bt_linkloss_connect_timer = xTimerCreate("bt_linkloss_connect_timer", 500, pdFALSE, 0, bt_linkloss_connect_timer_cb );
    }
}

uint8_t user_bt_get_state(uint8_t dev_index)
{
    uint8_t state = BT_STATE_IDLE;
    
    switch(user_bt_env.dev[dev_index].state)
    {
        case BT_LINK_STATE_IDLE:
            state = BT_STATE_IDLE;
            break;
        
        case BT_LINK_STATE_CONNECTING:
            state = BT_STATE_CONNECTING;
            break;
        
        case BT_LINK_STATE_DISCONNECTING:
            state = BT_STATE_DISCONNECTING;
            break;
        
        case BT_LINK_STATE_ACL_CONNECTED:
        case BT_LINK_STATE_PROFILE_CONNECTED:
        {
            state = BT_STATE_CONNECTED;
            if(user_bt_env.dev[dev_index].active == HF_CALL_ACTIVE){
                state = BT_STATE_HFP_CALLACTIVE;
            }
            else if(user_bt_env.dev[dev_index].setup_state == HF_CALL_SETUP_IN){
                state = BT_STATE_HFP_INCOMMING;
            }
            else if((user_bt_env.dev[dev_index].setup_state == HF_CALL_SETUP_OUT)
                ||(user_bt_env.dev[dev_index].setup_state == HF_CALL_SETUP_ALERT)){
                state = BT_STATE_HFP_OUTGOING;
            }else if(user_bt_env.dev[dev_index].conFlags & LINK_STATUS_MEDIA_PLAYING){
                state = BT_STATE_MEDIA_PLAYING;
            }    
        }
        break;        
    }
    
    return state;
}

BtStatus bt_enter_pairing(uint8_t access, BtAccessModeInfo *info)
{
    BtStatus status = BT_STATUS_PENDING;
    struct bt_connect_elt_t *elt;
    printf("bt enter pairing\r\n");
   
    
    
    if((access == BAM_NOT_ACCESSIBLE) || (access > BAM_GENERAL_ACCESSIBLE)){
        return BT_STATUS_INVALID_PARM;
    }
    if(user_bt_env.access_state == access){
        return BT_STATUS_SUCCESS;
    }
    
    //TBD,only change nonconnected access state
    status = ME_SetAccessibleModeNC(access, info);
    if(status == BT_STATUS_PENDING){
        elt = (struct bt_connect_elt_t *)btdm_malloc(sizeof(struct bt_connect_elt_t));
        elt->action = BT_ACTION_ACCESS;
        GLOBAL_INT_DISABLE();
        co_list_push_back(&user_bt_env.op_list,&elt->hdr);
        user_bt_env.action_cnt ++;
        GLOBAL_INT_RESTORE();
    }
    
    return status;
}

BtStatus bt_exit_pairing(void)
{
    BtStatus status = BT_STATUS_PENDING;
    struct bt_connect_elt_t *elt;

    status = ME_SetAccessibleModeNC(BAM_NOT_ACCESSIBLE, NULL);
    if(status == BT_STATUS_PENDING){
        elt = (struct bt_connect_elt_t *)btdm_malloc(sizeof(struct bt_connect_elt_t));
        elt->action = BT_ACTION_ACCESS;
        GLOBAL_INT_DISABLE();
        co_list_push_back(&user_bt_env.op_list,&elt->hdr);
        user_bt_env.action_cnt ++;
        GLOBAL_INT_RESTORE();
    }

    return status;
}

BtStatus bt_answer_call(uint8_t dev_index)
{
    HfCommand *cmd;
    uint8_t state = user_bt_get_state(dev_index);
    
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    
    if(state != BT_STATE_HFP_INCOMMING){
        return BT_STATUS_FAILED;
    }
    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_AnswerCall(user_bt_env.dev[dev_index].hf_chan, cmd);
}

BtStatus bt_dial_number(uint8_t dev_index, uint8_t *number, uint16_t len)
{

    HfCommand *cmd;
    
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_DialNumber(user_bt_env.dev[dev_index].hf_chan, number, len, cmd);
}

BtStatus bt_redial(uint8_t dev_index)
{
    HfCommand *cmd;
    
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_Redial(user_bt_env.dev[dev_index].hf_chan, cmd);
}

BtStatus bt_call_hold(uint8_t dev_index, HfHoldAction action, uint8_t index)
{
    HfCommand *cmd;
    
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_CallHold(user_bt_env.dev[dev_index].hf_chan, action, index, cmd);
}
                     
BtStatus bt_hang_up(uint8_t dev_index)
{
    HfCommand *cmd;
    uint8_t state = user_bt_get_state(dev_index);

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    printf("state = %d\r\n",state);
    if((state != BT_STATE_HFP_INCOMMING) && (state != BT_STATE_HFP_OUTGOING) && (state != BT_STATE_HFP_CALLACTIVE)){
        return BT_STATUS_FAILED;
    }
    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_Hangup(user_bt_env.dev[dev_index].hf_chan, cmd);
}

BtStatus bt_list_current_calls(uint8_t dev_index)
{
    HfCommand *cmd;
    uint8_t state = user_bt_get_state(dev_index);

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    printf("state = %d\r\n",state);

    if((state != BT_STATE_HFP_INCOMMING) && (state != BT_STATE_HFP_OUTGOING) && (state != BT_STATE_HFP_CALLACTIVE)){
        return BT_STATUS_FAILED;
    }
    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_ListCurrentCalls(user_bt_env.dev[dev_index].hf_chan, cmd);
}

BtStatus bt_transfer_sco(uint8_t dev_index)
{
    HfCommand *cmd;
    uint8_t state = user_bt_get_state(dev_index);

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    if(state < BT_STATE_CONNECTED){
        return BT_STATUS_FAILED;
    }
    printf("conFlags = %d\r\n",user_bt_env.dev[dev_index].conFlags);
    if(user_bt_env.dev[dev_index].conFlags & LINK_STATUS_SCO_CONNECTED){
        return HF_DisconnectAudioLink(user_bt_env.dev[dev_index].hf_chan);
    }else{
        cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
        //return HF_CreateAudioLink(user_bt_env.dev[dev_index].hf_chan);
        return HF_CodecConnectionReq(user_bt_env.dev[dev_index].hf_chan, cmd);
    }
}

BtStatus bt_send_dtmf(uint8_t dev_index, uint8_t dtmf)
{
    HfCommand *cmd;

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_GenerateDtmf(user_bt_env.dev[dev_index].hf_chan, dtmf, cmd);
}

BtStatus bt_report_mic_volume(uint8_t dev_index, uint8_t vol)
{
    HfCommand *cmd;
    uint8_t state = user_bt_get_state(dev_index);

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    if((state != BT_STATE_HFP_INCOMMING) && (state != BT_STATE_HFP_OUTGOING) && (state != BT_STATE_HFP_CALLACTIVE)){
        return BT_STATUS_FAILED;
    }
    
    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_ReportMicVolume(user_bt_env.dev[dev_index].hf_chan, vol, cmd);
}

BtStatus bt_report_spk_volume(uint8_t dev_index, uint8_t vol)
{
    HfCommand *cmd;
    uint8_t state = user_bt_get_state(dev_index);

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    if((state != BT_STATE_HFP_INCOMMING) && (state != BT_STATE_HFP_OUTGOING) && (state != BT_STATE_HFP_CALLACTIVE)){
        return BT_STATUS_FAILED;
    }
    
    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_ReportSpeakerVolume(user_bt_env.dev[dev_index].hf_chan, vol, cmd);
}

BtStatus bt_send_hf_cmd(uint8_t dev_index, const uint8_t *at_str)
{
    HfCommand *cmd;

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_SendAtCommand(user_bt_env.dev[dev_index].hf_chan, (const char*)at_str, cmd);
}

BtStatus bt_enable_voice_recognition(uint8_t dev_index, uint8_t enabled)
{
    HfCommand *cmd;

    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    cmd = (HfCommand *)btdm_malloc(sizeof(HfCommand));
    return HF_EnableVoiceRecognition(user_bt_env.dev[dev_index].hf_chan, enabled, cmd);
}

uint8_t bt_is_voice_rec_active(uint8_t dev_index)
{
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].hf_chan == NULL)){
        return 0;
    }
    return HF_IsVoiceRecActive(user_bt_env.dev[dev_index].hf_chan); 
}

BtStatus bt_set_media_volume(uint8_t dev_index, uint8_t volume)
{
    AvrcpAdvancedPdu *pdu;
    BtStatus status;
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].rcp_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }

    pdu = (AvrcpAdvancedPdu *)btdm_malloc(sizeof(AvrcpAdvancedPdu));
    pdu->parms = (uint8_t *)btdm_malloc(64);
    status = AVRCP_TgSetAbsoluteVolume(user_bt_env.dev[dev_index].rcp_chan, pdu,volume);
    if (status != BT_STATUS_PENDING) {
        btdm_free(pdu->parms);
        btdm_free(pdu);
    }
    return status;
}

BtStatus bt_get_playstatus(uint8_t dev_index)
{
    AvrcpAdvancedPdu *pdu;
    BtStatus status;
    
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].rcp_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    pdu = (AvrcpAdvancedPdu *)btdm_malloc(sizeof(AvrcpAdvancedPdu));
    pdu->parms = (uint8_t *)btdm_malloc(64);
    status = AVRCP_CtGetPlayStatus(user_bt_env.dev[dev_index].rcp_chan, pdu);
    if (status != BT_STATUS_PENDING) {
        btdm_free(pdu->parms);
        btdm_free(pdu);
    }
    return status;
}

BtStatus bt_get_media_info(uint8_t dev_index,AvrcpMediaAttrIdMask mediaMask)
{
    AvrcpAdvancedPdu *pdu;
    BtStatus status;
    
    if((dev_index >= NUM_BT_DEVICES) || (user_bt_env.dev[dev_index].rcp_chan == NULL)){
        return BT_STATUS_INVALID_PARM;
    }
    pdu = (AvrcpAdvancedPdu *)btdm_malloc(sizeof(AvrcpAdvancedPdu));
    pdu->parms = (uint8_t *)btdm_malloc(64);
    status = AVRCP_CtGetMediaInfo(user_bt_env.dev[dev_index].rcp_chan, pdu, mediaMask);
    if (status != BT_STATUS_PENDING) {
        btdm_free(pdu->parms);
        btdm_free(pdu);
    }
    return status;
}

// 音频相关变量
static enum {
    APP_AUDIO_MODE_IDLE,
    APP_AUDIO_MODE_A2DP_SINK,
} audio_mode = APP_AUDIO_MODE_IDLE;

static audio_scene_t *audio_scene = NULL;
static bool audio_pa_enabled = false;
static bool audio_playing = false;

// 音量控制变量
uint8_t g_volume_level = 127; // 默认最大音量 (0-127)

// SBC解码任务相关
#define SBC_DECODE_QUEUE_SIZE 5  // 从5减少到3，节省内存
#define SBC_DECODE_TASK_STACK_SIZE 1024  // 从1024减少到512，节省内存
#define SBC_DECODE_TASK_PRIORITY 7  // 从6降低到3，减少CPU占用和任务冲突

// SBC解码任务队列项结构
typedef struct {
    uint8_t *data;
    uint32_t length;
} sbc_decode_item_t;

// SBC解码任务句柄和队列
static TaskHandle_t sbc_decode_task_handle = NULL;
static QueueHandle_t sbc_decode_queue = NULL;
static bool sbc_decode_task_running = false;

// 真实的SBC解码器
static sbc_t sbc_decoder;
static bool sbc_decoder_initialized = false;
static struct sbc_frame sbc_frame_info;
static int16_t pcm_buffer_left[128]; // 从256减少到128，节省内存
static int16_t pcm_buffer_right[128]; // 从256减少到128，节省内存
static uint32_t audio_sample_rate = 44100; // 默认采样率

// 软件FIFO缓冲区 - 使用y_ringbuf循环队列
RINGBUF_st *s_audio_ringbuf = NULL;  // 改为全局变量，移除static

// 函数声明
void audio_hw_init(uint32_t sample_rate);
void audio_scene_destroy(audio_scene_t *scene);
bool audio_scene_dac_is_ready(audio_scene_t *scene);
void audio_scene_recv_raw_data(audio_scene_t *scene, bool valid, uint8_t *buffer, uint32_t length);
void app_audio_a2dp_sink_start(audio_type_t audio_type, uint32_t sample_rate);
void app_audio_a2dp_sink_stop(void);
void app_audio_a2dp_sink_play(uint8_t *buffer, uint32_t length);
bool app_audio_is_playing(void);
void app_audio_force_prevent_sleep(void);
void app_audio_allow_sleep(void);
void app_audio_play_test_tone(void);
void app_audio_enable_dac_interrupt(void);
// void audio_scene_init(uint32_t stack_size, uint8_t priority); // 移除重复声明

// SBC解码相关函数声明
static void play_audio_via_sbc_decode(uint8_t *sbc_data, uint32_t length);
static bool send_sbc_data_to_decode_task(uint8_t *sbc_data, uint32_t length);
static bool start_sbc_decode_task(void);
static void stop_sbc_decode_task(void);
static void sbc_decode_task(void *pvParameters);
static void audio_set_playing_state(bool playing);

// SBC解码任务函数
static void sbc_decode_task(void *pvParameters)
{
    sbc_decode_item_t item;

    printf("sbc_decode_task started\r\n");

    while (1)
    {
        if (xQueueReceive(sbc_decode_queue, &item, portMAX_DELAY) == pdPASS)
        {
            // 恢复正常解码流程
            play_audio_via_sbc_decode(item.data, item.length);

            // 释放之前分配的内存
            btdm_free(item.data);
        }
    }
}

// 启动SBC解码任务
static bool start_sbc_decode_task(void)
{
    if (sbc_decode_task_running) {
        return true; // 任务已经在运行
    }
    
    // 创建解码队列
    sbc_decode_queue = xQueueCreate(SBC_DECODE_QUEUE_SIZE, sizeof(sbc_decode_item_t));
    if (sbc_decode_queue == NULL) {
        printf("Failed to create SBC decode queue\r\n");
        return false;
    }
    
    // 创建解码任务
    sbc_decode_task_running = true;
    BaseType_t result = xTaskCreate(
        sbc_decode_task,
        "SBC_Decode",
        SBC_DECODE_TASK_STACK_SIZE,
        NULL,
        SBC_DECODE_TASK_PRIORITY,
        &sbc_decode_task_handle
    );
    
    if (result != pdPASS) {
        printf("Failed to create SBC decode task\r\n");
        sbc_decode_task_running = false;
        vQueueDelete(sbc_decode_queue);
        sbc_decode_queue = NULL;
        return false;
    }
    
    printf("SBC decode task created successfully\r\n");
    return true;
}

// 停止SBC解码任务
static void stop_sbc_decode_task(void)
{
    if (!sbc_decode_task_running) {
        return;
    }
    
    // 停止任务
    sbc_decode_task_running = false;
    
    // 等待任务结束
    if (sbc_decode_task_handle) {
        vTaskDelete(sbc_decode_task_handle);
        sbc_decode_task_handle = NULL;
    }
    
    // 清空队列
    if (sbc_decode_queue) {
        // 清空队列中的所有项目
        sbc_decode_item_t decode_item;
        while (xQueueReceive(sbc_decode_queue, &decode_item, 0) == pdTRUE) {
            if (decode_item.data) {
                btdm_free(decode_item.data);
            }
        }
        
        vQueueDelete(sbc_decode_queue);
        sbc_decode_queue = NULL;
    }
    
    printf("SBC decode task stopped\r\n");
}

// 发送SBC数据到解码任务
static bool send_sbc_data_to_decode_task(uint8_t *sbc_data, uint32_t length)
{
    if (!sbc_decode_task_running || !sbc_decode_queue) {
        return false;
    }

    // 分配内存并复制数据
    uint8_t *data_copy = (uint8_t *)btdm_malloc(length);
    if (!data_copy) {
        // Not safe to print from ISR
        return false;
    }

    memcpy(data_copy, sbc_data, length);

    // 创建队列项
    sbc_decode_item_t decode_item = {
        .data = data_copy,
        .length = length
    };

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    // 发送到队列 (ISR safe)
    if (xQueueSendFromISR(sbc_decode_queue, &decode_item, &xHigherPriorityTaskWoken) != pdTRUE) {
        btdm_free(data_copy);
        return false;
    }
    
    // 如果更高优先级的任务被唤醒，请求上下文切换
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

    return true;
}

// 音频播放状态管理
static void audio_set_playing_state(bool playing)
{
    static bool last_playing_state = false;
    
    if (playing != last_playing_state) {
        audio_playing = playing;
        if (playing) {
            system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
            printf("Audio playing started - sleep prevented\r\n");
        } else {
            system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
            printf("Audio playing stopped - sleep allowed\r\n");
        }
        last_playing_state = playing;
    }
}

// 简化的音频场景实现
static audio_scene_t *dummy_audio_scene = (audio_scene_t *)1;

audio_scene_t *audio_scene_create(int scene_type, void *param)
{
    printf("audio_scene_create: type=%d\r\n", scene_type);
    
    // 初始化音频硬件 - 此调用已移至 bt_update_conn_status，此处移除
    // audio_hw_init();
    
    return dummy_audio_scene;
}

void audio_scene_destroy(audio_scene_t *scene)
{
    printf("audio_scene_destroy\r\n");
    audio_set_playing_state(false);
    
    // 清理SBC解码器
    if (sbc_decoder_initialized) {
        sbc_decoder_initialized = false;
        printf("SBC decoder cleaned up\r\n");
    }
    
    printf("Audio scene destroyed\r\n");
}

bool audio_scene_dac_is_ready(audio_scene_t *scene)
{
    return true; // 简化实现
}

void audio_scene_recv_raw_data(audio_scene_t *scene, bool valid, uint8_t *buffer, uint32_t length)
{
    if (valid && buffer && length > 0) {
        // 使用SBC解码播放音频
        play_audio_via_sbc_decode(buffer, length);
        audio_set_playing_state(true);
    }
}

void app_audio_a2dp_sink_start(audio_type_t audio_type, uint32_t sample_rate)
{
    printf("app_audio_a2dp_sink_start: type=%d, rate=%d\r\n", audio_type, sample_rate);
    
    // 保存采样率
    audio_sample_rate = sample_rate;
    
    // DAC已在audio_hw_init中根据正确的采样率初始化，此处无需再设置
    // printf("Configuring DAC for sample rate: %d Hz\r\n", sample_rate);
    // app_dac_set_sample_rate(sample_rate);
    
    // 启动SBC解码任务
    if (!start_sbc_decode_task()) {
        printf("Failed to start SBC decode task\r\n");
        return;
    }
    
    // 创建音频场景
    audio_scene = audio_scene_create(0, NULL);
    if (audio_scene) {
        audio_mode = APP_AUDIO_MODE_A2DP_SINK;
        printf("A2DP sink audio scene created successfully\r\n");
    }
}

void app_audio_a2dp_sink_stop(void)
{
    printf("app_audio_a2dp_sink_stop\r\n");
    
    // 停止SBC解码任务
    stop_sbc_decode_task();
    
    if (audio_scene) {
        audio_scene_destroy(audio_scene);
        audio_scene = NULL;
    }
    
    // 清理ringbuf
    if (s_audio_ringbuf != NULL) {
        y_ringbuf_destroy(s_audio_ringbuf);
        s_audio_ringbuf = NULL;
        printf("app_audio_a2dp_sink_stop: ringbuf destroyed\r\n");
    }
    
    audio_mode = APP_AUDIO_MODE_IDLE;
    audio_set_playing_state(false);
    printf("A2DP sink stopped\r\n");
}

void app_audio_a2dp_sink_play(uint8_t *buffer, uint32_t length)
{
    if (audio_scene && buffer && length > 0) {
        // 添加调试信息 - 大幅减少频率
        static uint32_t play_count = 0;
        play_count++;
        if (play_count % 50 == 0) { // 从1000改为50，大幅增加调试频率
            printf("A2DP data received: length=%d, buffer[0]=0x%02X, buffer[1]=0x%02X\r\n", 
                   length, buffer[0], buffer[1]);
        }
        
        audio_scene_recv_raw_data(audio_scene, true, buffer, length);
    }
}

bool app_audio_is_playing(void)
{
    return audio_playing;
}

void app_audio_force_prevent_sleep(void)
{
    system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
}

void app_audio_allow_sleep(void)
{
    system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_A2DP_ONGOING);
}

void app_audio_play_test_tone(void)
{
    printf("app_audio_play_test_tone: Starting test tone...\r\n");
    // app_dac_test_start(); // 已删除的函数
}

void app_audio_enable_dac_interrupt(void)
{
    printf("app_audio_enable_dac_interrupt: Enabling DAC interrupt...\r\n");
    psd_dac_int_enable(PSD_DAC_INT_DACFF_L_AEMPTY);
    printf("DAC interrupt enabled\r\n");
}

void audio_hw_init(uint32_t sample_rate)
{
    static bool audio_hw_initialized = false;
    
    if (audio_hw_initialized) {
        printf("audio_hw_init: Audio hardware already initialized, skipping...\r\n");
        return;
    }
    
    printf("audio_hw_init: Initializing audio hardware...\r\n");
    
    // 初始化功放
    app_dac_pa_init();
    app_dac_pa_ctrl(1);
    printf("audio_hw_init: PA initialized and enabled\r\n");
    
    // 初始化DAC
    app_dac_init(sample_rate);
    printf("audio_hw_init: DAC initialized\r\n");
    
    // 初始化y_ringbuf循环队列 - 替换原来的FIFO初始化
    if (s_audio_ringbuf == NULL) {
        s_audio_ringbuf = y_ringbuf_create(1024 * 6); // 6KB缓冲区，减少内存使用
        if (s_audio_ringbuf == NULL) {
            printf("audio_hw_init: Failed to create y_ringbuf!\r\n");
            return;
        }
        printf("audio_hw_init: y_ringbuf created successfully, size=%d bytes\r\n", 1024 * 6);
    }
    
    // 添加ringbuf状态检查
    printf("RINGBUF INIT CHECK: used=%d, free=%d, total=%d\r\n",
           y_ringbuf_get_used_size(s_audio_ringbuf), 
           y_ringbuf_get_free_size(s_audio_ringbuf),
           1024 * 10);
    
    printf("audio_hw_init: Software ringbuf initialized\r\n");
    
    // DAC中断已在app_dac.c中启用，无需重复启用
    printf("audio_hw_init: DAC interrupt already enabled in app_dac.c\r\n");
    
    audio_hw_initialized = true;
    printf("audio_hw_init: Audio hardware initialization completed\r\n");
}

void audio_scene_init(uint32_t stack_size, uint8_t priority)
{
    printf("audio_scene_init: stack_size=%d, priority=%d\r\n", stack_size, priority);
    // 音频场景初始化完成
}

// 音频相关函数声明 - 使用原始的app_audio.c中的函数
extern void app_audio_a2dp_sink_start(audio_type_t audio_type, uint32_t sample_rate);
extern void app_audio_a2dp_sink_stop(void);
extern void app_audio_a2dp_sink_play(uint8_t *buffer, uint32_t length);
// extern void audio_hw_init(void);

// SBC解码和音频播放函数 - 在任务中执行
static void play_audio_via_sbc_decode(uint8_t *sbc_data, uint32_t length)
{
    if (!sbc_data || length == 0) {
        return;
    }
    
    // 初始化SBC解码器（如果未初始化）
    if (!sbc_decoder_initialized) {
        sbc_reset(&sbc_decoder);
        
        // 根据A2DP配置设置解码器参数
        // 从日志看，SBC配置是 0x21,15,2,35
        // 0x21 = 00100001: 44.1kHz, 8subbands, 16blocks, joint stereo
        // 15 = 00010101: loudness allocation, 16blocks, 8subbands  
        // 02 = 00000010: 2 channels
        // 35 = 00110101: bitpool = 53
        
        sbc_decoder.nchannels = 2;  // 2 channels
        sbc_decoder.nblocks = 16;   // 16 blocks
        sbc_decoder.nsubbands = 8;  // 8 subbands
        
        printf("SBC_DECODE: manual config - channels=%d, blocks=%d, subbands=%d\r\n",
               sbc_decoder.nchannels, sbc_decoder.nblocks, sbc_decoder.nsubbands);
        
        sbc_decoder_initialized = true;
        printf("SBC_DECODE: decoder initialized with manual config\r\n");
    }
    
    // 循环分帧处理 - 将数据包拆解成多个SBC帧
    uint32_t offset = 0;
    uint32_t frame_count = 0;
    
    while (offset < length) {
        // 检查剩余数据是否足够包含SBC帧头
        if (offset + 4 > length) {
            break;
        }
        
        // 检查同步字
        if (sbc_data[offset] != 0x9C) {
            // 寻找下一个同步字
            while (offset < length && sbc_data[offset] != 0x9C) {
                offset++;
            }
            if (offset >= length) break;
        }
        
        // 探测当前帧的大小
        struct sbc_frame current_frame;
        int probe_result = sbc_probe(&sbc_data[offset], &current_frame);
        
        if (probe_result != 0) {
            offset++; // 跳过这个字节，继续寻找
            continue;
        }
        
        // 计算帧大小
        uint32_t frame_size = sbc_get_frame_size(&current_frame);
        if (frame_size == 0 || frame_size > 512) { // 限制最大帧大小
            offset++;
            continue;
        }
        
        // 检查剩余数据是否足够包含完整帧
        if (offset + frame_size > length) {
            break;
        }
        
        // 解码当前帧
        int decode_result = sbc_decode(&sbc_decoder, &sbc_data[offset], frame_size, &sbc_frame_info,
                                     pcm_buffer_left, 1, pcm_buffer_right, 1);
        
        if (decode_result < 0) {
            offset += frame_size; // 跳过这个帧，继续处理下一个
            continue;
        }
        
        // 获取解码后的样本数
        int samples_per_frame = sbc_frame_info.nblocks * sbc_frame_info.nsubbands;
        if (samples_per_frame == 0 || samples_per_frame > 256) {
            offset += frame_size;
            continue;
        }
        
        // 将PCM数据转换为DAC格式并写入FIFO
        int16_t dac_frame_buffer[256]; // 增加缓冲区大小以容纳更多重采样数据
        
        // 正确的重采样：44.1kHz -> 48kHz
        // 重采样比例 = 48/44.1 ≈ 1.088
        int resampled_samples = 0;
        float resample_ratio = 48.0f / 44.1f; // 约1.088
        
        // 计算重采样后的样本数
        int expected_output_samples = (int)(samples_per_frame * resample_ratio + 0.5f);
        
        // 使用线性插值重采样算法
        float input_pos = 0.0f;
        float step = 1.0f / resample_ratio; // 输入步长
        
        for (int i = 0; i < expected_output_samples && resampled_samples < 256; i++) {
            // 计算对应的输入位置
            float input_index = input_pos;
            int input_idx1 = (int)input_index;
            int input_idx2 = input_idx1 + 1;
            
            // 边界检查
            if (input_idx1 >= samples_per_frame) break;
            if (input_idx2 >= samples_per_frame) input_idx2 = input_idx1;
            
            // 获取输入样本
            int16_t sample1, sample2;
            if (sbc_frame_info.mode == SBC_MODE_MONO) {
                sample1 = pcm_buffer_left[input_idx1];
                sample2 = pcm_buffer_left[input_idx2];
            } else {
                // 立体声模式，混合为单声道
                int32_t mixed1 = (int32_t)pcm_buffer_left[input_idx1] + (int32_t)pcm_buffer_right[input_idx1];
                int32_t mixed2 = (int32_t)pcm_buffer_left[input_idx2] + (int32_t)pcm_buffer_right[input_idx2];
                sample1 = (int16_t)(mixed1 >> 1);
                sample2 = (int16_t)(mixed2 >> 1);
            }
            
            // 限制PCM值范围，避免溢出
            if (sample1 > 32767) sample1 = 32767;
            if (sample1 < -32768) sample1 = -32768;
            if (sample2 > 32767) sample2 = 32767;
            if (sample2 < -32768) sample2 = -32768;
            
            // 线性插值
            float fraction = input_index - input_idx1;
            int32_t interpolated = (int32_t)sample1 + (int32_t)((sample2 - sample1) * fraction);
            
            // 应用软件音量控制
            // AVRCP音量范围0-127，转换为0.0-1.0的增益
            float volume_gain = (float)g_volume_level / 127.0f;
            interpolated = (int32_t)(interpolated * volume_gain);
            
            // 限制插值结果
            if (interpolated > 32767) interpolated = 32767;
            if (interpolated < -32768) interpolated = -32768;
            
            dac_frame_buffer[resampled_samples++] = (int16_t)interpolated;
            
            // 更新输入位置
            input_pos += step;
        }
        
        // 如果没有重采样输出，使用原始数据
        if (resampled_samples == 0) {
            resampled_samples = samples_per_frame;
            for (int i = 0; i < samples_per_frame && i < 256; i++) {
                int16_t sample;
                if (sbc_frame_info.mode == SBC_MODE_MONO) {
                    sample = pcm_buffer_left[i];
                } else {
                    int32_t mixed = (int32_t)pcm_buffer_left[i] + (int32_t)pcm_buffer_right[i];
                    sample = (int16_t)(mixed >> 1);
                }
                
                // 应用软件音量控制
                float volume_gain = (float)g_volume_level / 127.0f;
                int32_t volume_adjusted = (int32_t)(sample * volume_gain);
                
                if (volume_adjusted > 32767) volume_adjusted = 32767;
                if (volume_adjusted < -32768) volume_adjusted = -32768;
                
                dac_frame_buffer[i] = (int16_t)volume_adjusted;
            }
        }
        
        // 添加重采样调试信息
        static uint32_t resample_debug_count = 0;
        resample_debug_count++;
        if (resample_debug_count % 2000 == 0) { // 从500增加到2000，减少打印频率
            printf("RESAMPLE_DEBUG: input=%d, output=%d, ratio=%.3f, expected=%.1f\r\n", 
                   samples_per_frame, resampled_samples, resample_ratio, (float)expected_output_samples);
        }
        
        // 将转换后的数据写入ringbuf
        uint32_t data_to_write_bytes = resampled_samples * sizeof(int16_t);
        
        // 检查ringbuf空间，如果空间不足，丢弃一些旧数据
        if (y_ringbuf_get_free_size(s_audio_ringbuf) < data_to_write_bytes) {
            // ringbuf空间不足，丢弃一些数据以腾出空间
            uint32_t need_to_discard = data_to_write_bytes - y_ringbuf_get_free_size(s_audio_ringbuf) + 512; // 增加预留空间
            if (y_ringbuf_get_used_size(s_audio_ringbuf) > need_to_discard) {
                uint8_t temp_buffer[512]; // 增加临时缓冲区大小
                uint32_t discard_len = (need_to_discard > sizeof(temp_buffer)) ? sizeof(temp_buffer) : need_to_discard;
                
                GLOBAL_INT_DISABLE();
                y_ringbuf_read_clear(s_audio_ringbuf, temp_buffer, discard_len);
                GLOBAL_INT_RESTORE();
                
                static uint32_t discard_count = 0;
                discard_count++;
                if (discard_count % 50 == 0) { // 增加打印频率
                    printf("SBC_DECODE: discarded %d bytes to prevent overflow\r\n", discard_len);
                }
            }
        }
        
        // 写入新数据
        bool write_success = false;
        if (y_ringbuf_get_free_size(s_audio_ringbuf) >= data_to_write_bytes) {
            GLOBAL_INT_DISABLE();
            write_success = y_ringbuf_write(s_audio_ringbuf, (uint8_t*)dac_frame_buffer, data_to_write_bytes);
            GLOBAL_INT_RESTORE();
            
            // 添加写入成功调试信息
            static uint32_t write_success_count = 0;
            write_success_count++;
            if (write_success_count % 2000 == 0) { // 从100增加到2000，大幅减少打印频率
                printf("SBC_DECODE: write success - %d bytes, ringbuf_used=%d/%d\r\n", 
                       data_to_write_bytes, y_ringbuf_get_used_size(s_audio_ringbuf), 4096);
            }
        }
        
        // 检查写入结果
        if (!write_success) {
            static uint32_t write_fail_count = 0;
            write_fail_count++;
            if (write_fail_count % 1000 == 0) { // 从50增加到1000，大幅减少打印频率
                printf("SBC_DECODE: write failed - tried %d bytes, ringbuf_free=%d\r\n", 
                       data_to_write_bytes, y_ringbuf_get_free_size(s_audio_ringbuf));
            }
        }
        
        // 移动到下一个帧
        offset += frame_size;
        frame_count++;
    }
    
    // 定期打印ringbuf状态
    static uint32_t status_count = 0;
    status_count++;
    if (status_count % 5000 == 0) { // 从1000增加到5000，大幅减少打印频率
        printf("SBC_DECODE: processed %d frames, ringbuf_used=%d/%d, resample_ratio=%.2f\r\n", 
               frame_count, y_ringbuf_get_used_size(s_audio_ringbuf), 1024 * 4, 48.0f/44.1f);
    }
}

